package com.ltcode.log.starter.utils;

import com.ltcode.log.starter.entity.*;
import com.ltcode.log.starter.entity.Throwable;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

import java.util.function.Consumer;
import java.util.function.Function;

public class LogHandleUtil {

    public static Object process(ProceedingJoinPoint point,
                               Function<Before, DataEntity> before,
                               Consumer<After> after,
                               Consumer<Throwable> throwable,
                               Consumer<End> end) {

        MethodSignature methodSignature = (MethodSignature) point.getSignature();
        DataEntity dataEntity = null;
        Object proceed = null;
        
        // 获取调用前的日志上下文
        ThreadLocalEntity parentContext = LogUtils.getThreadLocalEntity();
        
        try {
            // 调用 before 方法并获取 DataEntity
            dataEntity = before.apply(new Before(methodSignature));
            
            // 创建新的日志上下文
            ThreadLocalEntity childContext = ThreadLocalEntity.createCopy(parentContext);
            if (childContext == null) {
                childContext = new ThreadLocalEntity();
            }
            childContext.pushDataEntity(dataEntity);
            LogUtils.setThreadLocalEntity(childContext);

            // 执行目标方法
            proceed = point.proceed();

            // 调用 after 方法
            after.accept(new After(proceed, LogUtils.safeGetDataEntity()));
        } catch (java.lang.Throwable e) {
            // 调用 throwable 方法
            throwable.accept(new Throwable(e,  LogUtils.safeGetDataEntity()));
        } finally {
            // 调用 end 方法
            end.accept(new End(methodSignature,  LogUtils.safeGetDataEntity()));
            // 方法结束后清理当前线程的日志上下文
            LogUtils.remove();
        }

        return proceed;
    }
}
